<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // 什么是call、bind、apply？
    // call，apply，bind是JavaScript中用于改变普通函数this指向（无法改变箭头函数this指向）的方法，这三个函数实际上都是绑定
    //在Function构造函数的prototype上，而每一个函数都是Function的实例，因此每一个函数都可以直接调用call，apply， bind
    // call、bind、apply的使用

    // 1.call方法

    // 语法： function.call(thisArg, arg1, arg2, ...)。  其中thisArg是要设置为函数执行上下文的对象，
    // 也就是this要指向的对象，从第二个参数开始，arg1, arg2, ...是传递给函数的参数。通过使用call方法，
    // 可以将一个对象的方法应用到另一个对象上。
    // 定义一个对象
    const person1 = {
        name: 'person1',
        greet: function (name) {
            console.log(`Hello, ${this.name}!`);
        },
        greet1: function (name) {
            console.log(`Hello, ${name}!`);//打印参数
        }
    };
    // 定义另一个对象
    const person2 = {
        name: 'person2',
    };
    // 使用call方法将person1的greet方法应用到person2上
    person1.greet.call(person2); // 输出：Hello, person2!
    person1.greet1.call(person2, '小王'); // 输出：Hello, 小王!

    // 2.apply方法
    // 语法：function.apply(thisArg, [argsArray])。 其中thisArg是要设置为函数执行上下文的对象，
    // 也就是this要指向的对象，argsArray是一个包含参数的数组。
    // 通过使用apply方法，可以将一个对象的方法应用到另一个对象上，并使用数组作为参数。

    // function greet(name) {
    //     console.log(`Hello, ${name}!`);
    // }

    // const person = { name: 'John' };
    // greet.apply(person, ['Mary']); // 输出：Hello, Mary!

    // 3.bind方法
    //  语法：function.bind(thisArg, arg1, arg2, ...)。 其中thisArg是要绑定到函数执行上下文的对象，也就是this要指向的对象，
    //  从第二个参数开始，arg1, arg2, ...是传递给函数的参数。与call和apply方法不同，bind方法并不会立即执行函数，
    //  而是返回一个新函数，可以稍后调用。这对于事件处理程序和setTimeout函数等场景非常有用。

    // function greet(name) {
    //     console.log("Hello, " + name);
    // }
    // const delayedGreet = greet.bind(null, "John");
    // setTimeout(() => {
    //     delayedGreet()
    // }, 2000)

    // 4.call、bind、apply的区别

    // call可以直接调用函数，并传递参数列表，立即执行。
    // bind返回一个新函数，将绑定的对象作为this值，可以在绑定时或调用时传递参数，需要手动调用新函数执行。
    // apply可以直接调用函数，并传递参数列表，立即执行，参数以数组或类数组的形式传递。




    // let persoman = {
    //     name: "小王",
    //     say: function () {
    //         console.log("hellow" + this.name);
    //     }
    // }
    // let persoman1 = {
    //     name: "小李",
    //     like: function () {
    //         console.log(this.name + "喜欢唱歌");
    //     }
    // }
    // persoman.say()
    // persoman.say.call(persoman1);
    // persoman1.like()
    // persoman1.like.apply(persoman)
    // persoman1.like.bind(persoman)()
</script>

</html>